package modellayer;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;


/**
 * The class Order is to hold information about a given order and which products this order contains.
 * A object of the order is to be saved in the OrderContainer class.
 * 
 * @author Allan Eriksen, Christian Stidsborg, Andreas Rye, Casper Madsen, Stefan Bols 
 * @version 051213
 */
public class Order
{
    private static int counter; // This counter keeps track of how many Order objects
                                // there has been initialized
    private int orderNo;
    private String date;
    private double totalPrice;
    private boolean orderClosed;
    private ArrayList<PartOrder> partOrderList;
    private Clerk clerk;

	private Customer customer;
    private double totalPriceWithoutVAT;
    private double VAT;

    /**
     * This constructor initialises the Order object. In the constructor the static
     * counter field is being counted one time up. And the other fields are being
     * set to its defaults. Except the date. The date are set the current date.
     */
    public Order(Clerk clerk)
    {
        this.counter++;
        this.orderNo = counter;
        this.totalPrice = 0.0;
        this.orderClosed = false;
        this.partOrderList = new ArrayList<PartOrder>();
        this.clerk = clerk;
        
        // Finding the current date and time to assign our date field
        GregorianCalendar calendar = new GregorianCalendar(); // Creating a new instance of the calendar class
        int day = calendar.get(Calendar.DAY_OF_MONTH); // Taking out the day......
        int month = calendar.get(Calendar.MONTH)+1; // ...month
        int year = calendar.get(Calendar.YEAR); // ...year
        int hour = calendar.get(Calendar.HOUR_OF_DAY); // ...hour
        int minute = calendar.get(Calendar.MINUTE); // ...minute
        
        StringBuilder string = new StringBuilder(); // Creating a StringBuilder to build our String.
        string.append(day);
        string.append("/");
        string.append(month);
        string.append("/");
        string.append(year);
        string.append(" ");
        string.append(hour);
        string.append(":");
        string.append(minute);
        
        this.date = string.toString(); // Calling toString on the StringBuilder object and adds
                                       // the String to the date field
    }
    
    public Customer getCustomer() {
		return customer;
	}

	public boolean isOrderClosed() {
		return orderClosed;
	}

	public void setOrderClosed(boolean orderClosed) {
		this.orderClosed = orderClosed;
	}

	public String getDate() {
		return date;
	}

	public double getTotalPrice() {
		return totalPrice;
	}
	
    public Clerk getClerk() {
		return clerk;
	}

	/**
     * This method sets the Clerk there are handling the Order
     * 
     * @param Clerk The Clerk there are handling the Order
     */
    public void setClerk(Clerk clerk)
    {
        this.clerk = clerk;
    }
    
    public void setCustomer(Customer customer)
    {
    	this.customer = customer;
    }
    
    /**
     * This method adds partOrders to the orderlist.
     * It takes to paremters, the partOrder.
     * 
     * @param PartOrder The PartOrder there is to be added to the orderlist.
     */
    public void addPartOrder(PartOrder partOrder)
    {
    	partOrderList.add(partOrder);       
        
    }
    
    /**
     * This method change the state of the Order to closed.
     * 
     */
    public boolean closeOrder()
    {
    	if (isOrderReadyToClose()) {
    		this.orderClosed = true;
    	}
    	
    	return orderClosed;
    }
    
    private boolean isOrderReadyToClose()
    {
    	boolean ready = false;
    	if (clerk!=null && partOrderList.size() > 0) {
    		ready = true;
    	}
    	
    	return ready;
    }

    /**
     * This method creating the Order number and returns it
     * 
     * @return The Order number
     */
    public String getOrderNo()
    {
    	String add = "";
		 if (orderNo < 10) {
			add = "000000";
		} else if (orderNo < 100) {
			add = "00000";
		} else if (orderNo < 1000) {
			add = "0000";
		} else if (orderNo < 10000) {
			add = "000";
		} else if (orderNo < 100000) {
			add = "00";
		} else if (orderNo < 1000000) {
			add = "0";
		} else if (orderNo < 10000000) {
			add = "";
		} else {
			add = "err:";
		}
		return add+orderNo;
    }
    
    /**
     * This method returns the total price for the Order, inclusive VAT.
     * 
     * @return double The total price for the Order
     */
    public double getOrderPriceTotal()
    {
    	double newPrice;
		double currentPrice = 0;
		
    	for(PartOrder partOrder : partOrderList)
    	{
    		newPrice = partOrder.getTotalPrice();
			currentPrice = newPrice + currentPrice;
			totalPrice = currentPrice;
    	}
    	
        return totalPrice;
    }
    
    public void addProductCopy(ProductCopy productCopy)
    {
    	boolean newPart = false;
    	
    	PartOrder partOrder = checkIfProductHasAPartInTheOrder(productCopy.getProductObj().getProductNo());
    	if (partOrder == null) {
    		partOrder = new PartOrder();
    		newPart = true;
    	}
    	
		partOrder.addProductCopy(productCopy);
		
		if (newPart) {
			addPartOrder(partOrder);
		}
    }
    
    public void deletePartOrderAndReturnsItsCopies(String productNo) {
    	boolean found = false;
    	int listSize = partOrderList.size();
    	
    	for (int i = 0; i < listSize && !found; i++) {
    		PartOrder partOrder = partOrderList.get(i);
    		if (partOrder.getProductNo().equals(productNo)) {
    			Product product = ProductContainer.getInstance().getProductFromProductNo(productNo);
    			
    			for (ProductCopy productCopy : partOrder.getCopyList()) {
    				product.addProductCopy(productCopy);
    			}
    			
    			partOrderList.remove(i);
    			found = true;
    		}
    	}
    }
    
    private PartOrder checkIfProductHasAPartInTheOrder(String productNo) {
    	PartOrder found = null;
    	int listSize = partOrderList.size();
    	
    	for (int i = 0; i < listSize && found==null; i++) {
    		if (partOrderList.get(i).getProductNo().equals(productNo)) {
    			found = partOrderList.get(i);
    		}
    	}
    	
    	return found;
    }
    
    /**
     * This methods returns the orderlist
     * 
     * @return ArrayList<ProductCopy> ArrayList with ProductCopy objects, which are those there are added to the order list.
     */
    public ArrayList<PartOrder> getPartOrderList()
    {
        return partOrderList;
    }
    
    public double calculateVAT()
    {
    	VAT = getOrderPriceTotal() / 100 * 20;
    	
    	return VAT;
    }
    
    public double totalPriceWithoutVAT()
    {
    	totalPriceWithoutVAT = getOrderPriceTotal() - calculateVAT();
    	
    	return totalPriceWithoutVAT;
    }
}